package io.github.leon406.view.dialog

import android.app.Dialog
import android.os.Bundle
import android.view.View
import android.view.WindowManager
import android.widget.TextView
import androidx.annotation.IdRes
import androidx.annotation.LayoutRes
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatDialogFragment
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import me.leon.ui.R

abstract class AbsDialog : AppCompatDialogFragment() {

    private var screenWidth: Int = 0
    private var screenHeight: Int = 0
    private var dpi: Float = 0f
    var callback: DialogCallback? = null

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        screenWidth = resources.displayMetrics.widthPixels
        screenHeight = resources.displayMetrics.heightPixels
        dpi = resources.displayMetrics.density
        val dialog = Dialog(requireActivity(), setDialogStyle())
        dialog.setContentView(bindLayout())
        dialog.setCanceledOnTouchOutside(false)
        return dialog
    }

    private fun setDialogStyle(): Int {
        return R.style.dialog
    }

    fun show(fragment: Fragment, tag: String = "") {
        show(fragment.childFragmentManager, tag.ifEmpty { javaClass.canonicalName })
    }

    fun show(activity: FragmentActivity, tag: String = "") {
        show(activity.supportFragmentManager, tag.ifEmpty { javaClass.canonicalName })
    }

    open fun isShowing(): Boolean {
        return dialog != null && dialog!!.isShowing
    }

    @LayoutRes protected abstract fun bindLayout(): Int

    override fun onStart() {
        super.onStart()
        initDialog()
        setUpDialog()
    }

    fun <T : View> getView(@IdRes id: Int): T {
        return dialog?.findViewById<View>(id) as T
    }

    fun setText(@IdRes id: Int, text: String?): AbsDialog {
        val tv = getView<TextView>(id)
        tv.text = text
        return this
    }

    fun setText(@IdRes id: Int, @StringRes strId: Int): AbsDialog {
        val tv = getView<TextView>(id)
        tv.setText(strId)
        return this
    }

    protected abstract fun initDialog()

    open fun setUpDialog() {
        val dialog = dialog
        dialog?.run {
            val width = (screenWidth * 0.8 + 0.5).toInt()
            val height = -2
            window!!.setLayout(width, height)
            setDialogAttribute()
        }
    }

    private fun setDialogAttribute() {
        dialog?.window?.run { setAttribute(attributes) }
    }

    override fun dismiss() {
        dismissAllowingStateLoss()
    }

    fun setDialogCallback(callback: DialogCallback) {
        this.callback = callback
    }

    /** 子类自定义属性 */
    open fun setAttribute(params: WindowManager.LayoutParams) {
        // 子类实现
    }

    interface DialogCallback {
        fun confirm(msg: Any? = null)
        fun cancel()
    }
}

inline fun AbsDialog.addDialogCallback(crossinline confirm: () -> Unit): AbsDialog.DialogCallback {
    val cb =
        object : AbsDialog.DialogCallback {
            override fun confirm(msg: Any?) {
                confirm.invoke()
            }

            override fun cancel() {
                //nop
            }
        }
    setDialogCallback(cb)
    return cb
}
